const http = require('http');
const fs = require('fs');
const path = require('path');

const targetFile = process.argv[2] 
  ? path.join(__dirname, process.argv[2]) 
  : __filename;

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });

  // 1. 创建文件读取流：fs.createReadStream(path, options)
  const readStream = fs.createReadStream(targetFile, 'utf8');

  // 2. 处理流的事件
  // 流“可读”事件：当有数据可读时触发
  readStream.on('data', (chunk) => {
    console.log(`读取到数据块（大小：${chunk.length} 字节）`);
  });

  // 流“结束”事件：文件读取完成时触发
  readStream.on('end', () => {
    console.log(`文件 "${targetFile}" 读取完成`);
  });

  // 流“错误”事件：读取过程中发生错误时触发（如文件不存在）
  readStream.on('error', (err) => {
    const errorMsg = `错误：流读取文件失败\n原因：${err.message}`;
    res.end(errorMsg);
    console.error(errorMsg);
  });

  // 3. 使用管道（pipe）将流直接导向响应对象
  // 管道会自动管理数据流：读取数据 -> 写入响应 -> 完成后自动结束响应
  res.write(`成功通过流读取文件：${targetFile}\n（流模式：适合大文件，内存占用低）\n\n文件内容：\n`);
  readStream.pipe(res);
});

server.listen(8081, () => {
  console.log(`服务器已启动，监听端口 8081`);
  console.log(`当前读取目标：${targetFile}`);
  console.log(`请访问：http://localhost:8081 查看结果`);
});

/*
流与直接读取的核心区别

特性	       直接读取（readFile/open+read）	流读取（createReadStream）
内存占用	   一次性加载整个文件到内存	          分块读取，仅占用缓冲区大小内存
适用文件大小	小文件（<100MB）	             大文件（>100MB）或实时数据
操作复杂度	    简单（API 封装完整）           	稍复杂（需处理流事件）
数据处理方式	等待全部数据读取完成后处理	      边读边处理（实时响应）
资源释放	    自动释放	                   需监听 “end”/“error” 事件确保释放
*/